﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
using System.Runtime.InteropServices;
using System.Data;
using log4net;
using System.Net;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using TradePublish.Common;
using TradePublish.Service;
using System.Text;
namespace TradePublish.SysThread.Grasp
{
    /// <summary>
    /// 
    ///识别gif图片中注册号的类。只有1个线程在做gif分析工作
    ///
    ///1、根据别的线程所发现的最新公告期内的8类gif图片页面，分析gif图片，得到注册号信息。
    ///2、具体任务：修改REGNO_GIF,新增数据到TRADE_PUBLISH。
    /// </summary>
    public class AnalyGifThread
    {
        private Thread doThread;
        ILog log = null;



        private String url = "http://saicsearch.saic.gov.cn/gszj/sbgg/sbggpic/I/I_G.gif";//其中的G为匹配页码符


        public AnalyGifThread()
        {
            log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        }


        public void start()
        {
            doThread = new Thread(threadWork);
            doThread.IsBackground = true;
            doThread.Start();
        }
        /// <summary>
        /// 此函数作用：识别gif图片。 
        /// </summary>
        private void threadWork()
        {
            while (true)
            {
                RegnoGifManager regnoGifManager = new RegnoGifManager();
                TradePublishManager tradePublishManager = new TradePublishManager();
                //--------------------------获得尚未分析、采集的注册号-------------------------
                DataSet ds = regnoGifManager.getNoFinishedOne();//内部异常自己解决 ，按照时间正排列的第一个。

                if (ds != null && ds.Tables != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                {
                    log.Info("得到数据库表REGNO_GIF中尚未dll分析的公告" + ds.Tables[0].Rows.Count + "个");
                    #region 有待采集的
                    String urlNew = url.Replace("I", "" + ds.Tables[0].Rows[0]["ISSUE"].ToString());
                    Int32 id = Convert.ToInt32(ds.Tables[0].Rows[0]["ID"].ToString());
                    Int32 issue = Convert.ToInt32(ds.Tables[0].Rows[0]["ISSUE"].ToString());//期号
                    Int32 category = Convert.ToInt32(ds.Tables[0].Rows[0]["CATEGORY"].ToString());//八大类类别
                    Int32 startPageNo = Convert.ToInt32(ds.Tables[0].Rows[0]["START_PAGE_NO"].ToString());//开始页码
                    Int32 endPageNo = Convert.ToInt32(ds.Tables[0].Rows[0]["END_PAGE_NO"].ToString());//结束页码
                    ds = null;//释放资源
                    for (int i = startPageNo; i <= endPageNo; i++)
                    {//依次每页进行gif分析 
                        String gif = urlNew.Replace("G", "" + i);
                        #region 下载图片到本地/tmpGif/文件夹下
                        String filePath = Application.StartupPath + "\\tmpGif\\" + issue + "_" + i + ".gif";
                        int retryCount = 0;
                        bool success = false;
                        while (true)
                        {
                            try
                            {
                                log.Info(" 开始下载gif图片...");
                                SavePhotoFromUrl(filePath, gif);
                                success = true;
                                break;
                            }
                            catch (Exception ee)
                            {
                                log.Error(" 下载gif图片" + gif + "时发生异常", ee);
                                Thread.Sleep(5000);
                                retryCount++;
                                if (retryCount > 3 && ee.Message.IndexOf("(404)") >= 0)
                                {
                                    break;
                                }
                            }
                        }
                        if (!success)
                            continue;
                        #endregion

                        #region 根据本gif，获得本页面的多个注册号,英文冒号作为分隔符
                        StringBuilder regNosS = new StringBuilder("");
                        if (category == 0)
                        {
                            try
                            {
                                log.Info(" dll分析gif图片(" + gif + ")");
                                StringBuilder f = new StringBuilder(filePath);
                                GifAnalyUtil.DetectCha(f, regNosS);
                                //regNosS = Util.RandomNumeric(6) + ";" + Util.RandomNumeric(6) + ";" + Util.RandomNumeric(6) + ";" + Util.RandomNumeric(6);
                                log.Info(" 成功解析第一类gif图片(" + gif + ")获得注册号：" + regNosS);
                            }
                            catch (Exception exG)
                            {
                                log.Error("发生异常,解析第一类gif图片(" + gif + ")：", exG);
                                //  i--;
                                Thread.Sleep(1000);
                                continue;
                            }
                        }
                        else
                        {
                            //regNosS = new StringBuilder();
                            try
                            {
                                regNosS = new StringBuilder(8000);
                                log.Debug(" dll分析gif图片(" + gif + ")");
                                StringBuilder f = new StringBuilder(filePath);
                                GifAnalyUtil.DetectCha2(f, regNosS);
                                log.Info("成功解析非第一类gif图片(" + gif + ")获得注册号：" + regNosS);
                            }
                            catch (Exception exG)
                            {
                                log.Error("发生异常,解析非第一类gif图片(" + gif + ")：", exG);
                                //i--;
                                Thread.Sleep(1000);
                                continue;
                            }
                        }
                        //删除文件
                        try
                        {
                            File.Delete(filePath);
                        }
                        catch (Exception e)
                        {
                            log.Error(" 删除临时图片文件（" + filePath + "）发生异常：", e);
                        }
                        String[] regNos = regNosS.ToString().Split(';');
                        #endregion
                        for (int j = 0; j < regNos.Length; j++)
                        {
                            if (regNos[j] == null || regNos[j].Equals(""))
                            {
                                continue;
                            }
                            #region 添加到TRADE_PUBLISH，表示此部分商标数据尚未采集，等待采集线程去采集,异常自己处理，记录日志
                            while (true)
                            {
                                try
                                {
                                    tradePublishManager.insertHasAnalyGif(issue, category, regNos[j], gif);
                                    log.Info("dll对" + gif + "分析出来的注册号" + regNos[j] + "插入TRADE_PUBLISH完毕.");
                                    break;
                                }
                                catch (Exception ex)
                                {
                                    log.Info("数据库异常，dll对" + gif + "分析出来的注册号" + regNos[j] + "插入TRADE_PUBLISH异常.", ex);
                                    Thread.Sleep(1000);
                                }
                            }
                            #endregion
                        }
                        #region  更新页码，本页gif分析完毕,异常处理，日志记录
                        log.Info("当前gif页面【第" + issue + "期 第" + (i) + "页】分析完毕.");
                        //本gif页采集完毕，更新页码  
                        while (true)
                        {
                            try
                            {
                                regnoGifManager.updatePageNo(id, i + 1);
                                log.Debug("更新数据库REGNO_GIF表id=" + id + "完毕.");
                                break;
                            }
                            catch (Exception ee)
                            {
                                //数据库报错
                                log.Error("数据库异常，更新REGNO_GIF表id=" + id + "失败.", ee);
                                Thread.Sleep(5000);//休息 
                            }
                        }
                        #endregion
                    }
                    #region 本公告期本类的gif图片全部分析完毕  ,异常处理，日志记录
                    while (true)
                    {
                        try
                        {
                            regnoGifManager.updateFinish(id);
                            log.Debug("更新数据库REGNO_GIF表id=" + id + "为完成状态完毕.");
                            break;
                        }
                        catch (Exception ee)
                        {
                            log.Error("数据库异常，更新REGNO_GIF表id=" + id + "为完成状态失败.", ee);
                            Thread.Sleep(5000);//休息 
                        }
                    }
                    #endregion
                    #endregion
                }
                else
                {
                    log.Info("数据库表REGNO_GIF中无尚未分析的公告，本线程休息5分钟后重头再次查询数据库中尚未dll分析的公告.");
                    Thread.Sleep(60000);//休息1分钟
                }
            }
        }
        public static bool SavePhotoFromUrl(string FileName, string Url)
        {
            bool Value = false;
            WebResponse response = null;
            Stream stream = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                response = request.GetResponse();
                stream = response.GetResponseStream();
                if (!response.ContentType.ToLower().StartsWith("text/"))
                {
                    Value = SaveBinaryFile(response, FileName);
                }
            }
            catch (Exception err)
            {
                throw err;
            }
            return Value;
        }

        /// <summary>
        /// Save a binary file to disk.
        /// </summary>
        /// <param name="response">The response used to save the file</param>
        // 将二进制文件保存到磁盘
        private static bool SaveBinaryFile(WebResponse response, string FileName)
        {
            bool Value = true;
            byte[] buffer = new byte[1024];
            try
            {
                if (File.Exists(FileName))
                    File.Delete(FileName);
                Stream outStream = System.IO.File.Create(FileName);
                Stream inStream = response.GetResponseStream();

                int l;
                do
                {
                    l = inStream.Read(buffer, 0, buffer.Length);
                    if (l > 0)
                        outStream.Write(buffer, 0, l);
                }
                while (l > 0);

                outStream.Close();
                inStream.Close();
            }
            catch (Exception err)
            {
                throw err;
            }
            return Value;
        }

    }
}